//
// AWS Manager - A free AWS console application demonstrating advanced concepts
// Copyright (C) 2008-2010 Sean O'Dell. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.awsmanager.common;

import com.sun.data.provider.RowKey;
import com.sun.data.provider.impl.ObjectListDataProvider;
import com.sun.webui.jsf.model.Option;
import com.xerox.amazonws.ec2.AddressInfo;
import com.xerox.amazonws.ec2.EC2Exception;
import com.xerox.amazonws.ec2.Jec2;
import com.xerox.amazonws.sdb.Domain;
import com.xerox.amazonws.sdb.Item;
import com.xerox.amazonws.sdb.ItemAttribute;
import com.xerox.amazonws.sdb.SDBException;
import com.xerox.amazonws.sdb.SimpleDB;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Sean ODell
 */
public class EC2IPDataProvider extends ObjectListDataProvider {

    private ArrayList ec2IPsList = new ArrayList();
    private EC2Connection ec2connection;
    private SimpleDB simpleDB;
    private Domain sdbdomain = null;

    public EC2IPDataProvider() {
        setList(ec2IPsList);
        setObjectType(EC2IP.class);
    }

    public void load(EC2Connection ec2connection, SDBConnection sdbconnection,
            EC2InstanceDataProvider ec2InstanceDataProvider) {

        clearObjectList();

        if (ec2connection == null) {
            this.ec2connection = null;
            return;
        } else {
            this.ec2connection = ec2connection;
        }

        if ((this.ec2connection = ec2connection) == null) {
            return;
        }

        Item sdbitem = null;
        List<ItemAttribute> sdbattributes = null;
        String sdbdomainname = null;
        EC2Instance ec2instance = null;

        ArrayList<String> sdbattributesList = new ArrayList<String>();

        sdbattributesList.add("type");
        sdbattributesList.add("name");
        sdbattributesList.add("description");
        sdbattributesList.add("ownernamelast");
        sdbattributesList.add("ownernamelast");
        sdbattributesList.add("ownernamefirst");
        sdbattributesList.add("ownerdept");

        sdbdomain = null;

        if ((simpleDB = sdbconnection.getsimpleDB()) != null) {

            sdbdomainname = sdbconnection.getsdbdomain();

            try {
                sdbdomain = simpleDB.getDomain(sdbdomainname);
            } catch (SDBException ex) {
                sdbdomain = null;
                Logger.getLogger(EC2IPDataProvider.class.getName()).log(Level.SEVERE, null, ex);
            }

            try {
                sdbdomain.getItem("test").getAttributes();
            } catch (SDBException ex) {
                try {
                    sdbdomain = simpleDB.createDomain(sdbdomainname);
                } catch (SDBException ex1) {
                    Logger.getLogger(EC2IPDataProvider.class.getName()).log(Level.SEVERE, null, ex1);
                }
            }
        }

        List<AddressInfo> ec2ips = null;
        ArrayList<String> ec2Regions = ec2connection.getEc2RegionNames();
        EC2Region ec2RegionInfo = null;

        for (String ec2Region : ec2Regions) {

            ec2RegionInfo = (EC2Region) ec2connection.getEc2RegionInfo().get(ec2Region);
            List<String> params = new ArrayList<String>();

            try {
                ec2ips = ec2RegionInfo.getRegionConnection().describeAddresses(params);
            } catch (EC2Exception ex) {
                Logger.getLogger(EC2IPDataProvider.class.getName()).log(Level.SEVERE, null, ex);
            }

            for (AddressInfo ec2ip : ec2ips) {

                EC2IP ec2ipInfo = new EC2IP();
                ec2ipInfo.setRegion(ec2Region);
                ec2ipInfo.setpublicip(ec2ip.getPublicIp());
                ec2ipInfo.setinstanceId(ec2ip.getInstanceId());

                if (ec2ip.getInstanceId() != null) {
                    ec2instance = ec2InstanceDataProvider.getInstance(ec2ip.getInstanceId());
                    if (ec2instance != null) {
                        if (ec2instance.getinstname() != null) {
                            ec2ipInfo.seteipinstancename(ec2instance.getinstname());
                        }
                    }
                }

                getList().add(ec2ipInfo);

                if (sdbdomain != null) {
                    try {
                        sdbitem = sdbdomain.getItem(ec2ip.getPublicIp());
                        sdbattributes = sdbitem.getAttributes(sdbattributesList);
                    } catch (SDBException ex) {
                        Logger.getLogger(EC2InstanceDataProvider.class.getName()).log(Level.SEVERE, null, ex);
                    }

                    if (sdbattributes != null) {
                        if (sdbattributes.size() > 0) {
                            for (ItemAttribute attribute : sdbattributes) {
                                String attributename = attribute.getName();
                                if (attributename.equals("name")) {
                                    ec2ipInfo.seteipname(attribute.getValue());
                                } else if (attributename.equals("description")) {
                                    ec2ipInfo.seteipdesc(attribute.getValue());
                                } else if (attributename.equals("ownernamelast")) {
                                    ec2ipInfo.seteipownernamelast(attribute.getValue());
                                } else if (attributename.equals("ownernamefirst")) {
                                    ec2ipInfo.seteipownernamefirst(attribute.getValue());
                                } else if (attributename.equals("ownerdept")) {
                                    ec2ipInfo.seteipownerdept(attribute.getValue());
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public EC2IP getEC2IP(RowKey rowKey) {
        EC2IP ec2ip = (EC2IP) getObject(rowKey);
        return ec2ip;
    }

    public EC2IP getEC2IP(String id) {
        for (int i = 0; i < ec2IPsList.size(); i++) {
            EC2IP ec2ip = (EC2IP) ec2IPsList.get(i);
            if (ec2ip.getpublicip().equals(id)) {
                return ec2ip;
            }
        }
        return null;
    }

    public int getEC2IPIndex(String id) {
        for (int i = 0; i < ec2IPsList.size(); i++) {
            EC2IP ec2ip = (EC2IP) ec2IPsList.get(i);
            if (ec2ip.getpublicip().equals(id)) {
                return i;
            }
        }
        return -1;
    }

    public Boolean isInstanceIDUsed(String instanceid) {
        for (int i = 0; i < ec2IPsList.size(); i++) {
            EC2IP ec2ip = (EC2IP) ec2IPsList.get(i);
            if (ec2ip.getinstanceId().equals(instanceid)) {
                return true;
            }
        }
        return false;
    }

    public Option[] getEC2IPOptions() {
        int i = 0;
        Option[] ec2IPsOptions = new Option[ec2IPsList.size()];

        for (i = 0; i < ec2IPsList.size(); i++) {
            EC2IP ec2ip = (EC2IP) ec2IPsList.get(i);
            ec2IPsOptions[i] = new Option(ec2ip.getpublicip());
        }
        return ec2IPsOptions;
    }

    public String createEC2IP(Map eipInfo) {
        String statusMsg = new String();
        String eipRegion = null;
        String eipCountStr = null;
        int eipCount = 0;

        if (ec2connection == null) {
            statusMsg = statusMsg + "Please update user settings first.";
            return statusMsg;
        }

        eipCountStr = (String) eipInfo.get("eipCount");
        eipRegion = (String) eipInfo.get("eipRegion");
        eipCount = Integer.parseInt(eipCountStr);

        EC2Region ec2RegionInfo = null;
        ec2RegionInfo = (EC2Region) ec2connection.getEc2RegionInfo().get(eipRegion);

        for (int i = 1; i <= eipCount; i++) {
            try {
                if (ec2RegionInfo.getRegionConnection() != null) {
                    String ec2ipAddr = ec2RegionInfo.getRegionConnection().allocateAddress();
                    statusMsg = statusMsg + "Elastic IP added: " + eipRegion + ", " + ec2ipAddr + "\n";
                }
            } catch (EC2Exception ex) {
                statusMsg = statusMsg + "Error: " + ex + "\n";
                Logger.getLogger(EC2IPDataProvider.class.getName()).log(Level.SEVERE, null, ex);
                return statusMsg;
            }
        }

        return statusMsg;
    }

    public String releaseEC2IPs(RowKey[] selectedRowKeys) {
        String statusMsg = new String();
        EC2Region ec2RegionInfo = null;

        for (int i = 0; i < selectedRowKeys.length; i++) {
            RowKey rowKey = selectedRowKeys[i];
            EC2IP ec2ip = getEC2IP(rowKey);
            ec2RegionInfo = (EC2Region) ec2connection.getEc2RegionInfo().get(ec2ip.getRegion());
            try {
                ec2RegionInfo.getRegionConnection().releaseAddress(ec2ip.getpublicip());
                statusMsg = statusMsg + "Released Elastic IP: " + String.format("%-16s", ec2ip.getpublicip()) + "\n";
            } catch (EC2Exception ex) {
                statusMsg = statusMsg + "Error: " + ex + "\n";
                Logger.getLogger(EC2IPDataProvider.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return statusMsg;
    }

    public String associateEC2IP(String instanceid, String ipaddress, String region) {
        String statusMsg = new String();
        EC2Region ec2RegionInfo = null;
        ec2RegionInfo = (EC2Region) ec2connection.getEc2RegionInfo().get(region);
        try {
            ec2RegionInfo.getRegionConnection().associateAddress(instanceid, ipaddress);
        } catch (EC2Exception ex) {
            Logger.getLogger(EC2IPDataProvider.class.getName()).log(Level.SEVERE, null, ex);
        }
        return statusMsg;
    }

    public String disassociateEC2IPs(RowKey[] selectedRowKeys) {
        String statusMsg = new String();
        EC2Region ec2RegionInfo = null;
        for (int i = 0; i < selectedRowKeys.length; i++) {
            RowKey rowKey = selectedRowKeys[i];
            EC2IP ec2ip = getEC2IP(rowKey);
            ec2RegionInfo = (EC2Region) ec2connection.getEc2RegionInfo().get(ec2ip.getRegion());
            try {
                ec2RegionInfo.getRegionConnection().disassociateAddress(ec2ip.getpublicip());
                statusMsg = statusMsg + "Disassociated Elastic IP: " + String.format("%-16s", ec2ip.getpublicip()) + "\n";
            } catch (EC2Exception ex) {
                statusMsg = statusMsg + "Error: " + ex + "\n";
            }
        }
        return statusMsg;
    }

    public String updateEC2IP(Map ec2ipinfo) {

        int eipIndex = -1;
        String statusMsg = new String();
        Item sdbitem = null;
        List<ItemAttribute> sdbattributes = new ArrayList<ItemAttribute>();

        String eipid = (String) ec2ipinfo.get("eipid");

        if (sdbdomain != null) {
            try {
                sdbitem = sdbdomain.getItem(eipid);

                sdbattributes.add(new ItemAttribute("type", (String) ec2ipinfo.get("type"), true));
                sdbattributes.add(new ItemAttribute("name", (String) ec2ipinfo.get("eipname"), true));
                sdbattributes.add(new ItemAttribute("description", (String) ec2ipinfo.get("eipdesc"), true));
                sdbattributes.add(new ItemAttribute("ownernamelast", (String) ec2ipinfo.get("eipownernamelast"), true));
                sdbattributes.add(new ItemAttribute("ownernamefirst", (String) ec2ipinfo.get("eipownernamefirst"), true));
                sdbattributes.add(new ItemAttribute("ownerdept", (String) ec2ipinfo.get("eipownerdept"), true));

                sdbitem.putAttributes(sdbattributes);

                EC2IP ec2ip = getEC2IP(eipid);
                eipIndex = getEC2IPIndex(eipid);

                ec2ip.seteipname((String) ec2ipinfo.get("eipname"));
                ec2ip.seteipdesc((String) ec2ipinfo.get("eipdesc"));
                ec2ip.seteipownernamelast((String) ec2ipinfo.get("eipownernamelast"));
                ec2ip.seteipownernamefirst((String) ec2ipinfo.get("eipownernamefirst"));
                ec2ip.seteipownerdept((String) ec2ipinfo.get("eipownerdept"));

                ec2IPsList.set(eipIndex, ec2ip);

            } catch (SDBException ex) {
                Logger.getLogger(EC2InstanceDataProvider.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return statusMsg;
    }
}
